package com.lgy.ms.core.utils;

import com.lgy.ms.core.constant.RespCode;
import com.lgy.ms.core.exception.BusinessException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.Assert;
import org.springframework.util.FileCopyUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;


public class FileUtils {

	private static Logger log = LoggerFactory.getLogger(FileUtils.class);

	/**
	 * 将指定的对象写入指定的文件中
	 * 
	 * @param file
	 *            指定写入的文件
	 * @param objs
	 *            要写入的对象
	 */
	public static void doObjToFile(String file, Object[] objs) {
		ObjectOutputStream oos = null;
		try {
			FileOutputStream fos = new FileOutputStream(file);
			oos = new ObjectOutputStream(fos);
			for (int i = 0; i < objs.length; i++) {
				oos.writeObject(objs[i]);
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				oos.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	public static void doObjToFile(String privateFile, String publicFile, Object[] objs) {
		ObjectOutputStream oosPrivate = null;
		ObjectOutputStream oosPublic = null;

		try {
			FileOutputStream fosPrivate = new FileOutputStream(privateFile);
			FileOutputStream fosPublic = new FileOutputStream(publicFile);
			oosPrivate = new ObjectOutputStream(fosPrivate);
			oosPublic = new ObjectOutputStream(fosPublic);
			for (int i = 0; i < objs.length; i++) {
				if (objs[i] instanceof PublicKey) {
					oosPublic.writeObject(objs[i]);
				} else if (objs[i] instanceof PrivateKey) {
					oosPrivate.writeObject(objs[i]);
				}

			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				oosPrivate.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	public static PublicKey getPublicKey(String publicFile) throws Exception{
		FileInputStream fis = new FileInputStream(publicFile);
		InputStreamReader inputReader = new InputStreamReader(fis);
		BufferedReader bufferReader = new BufferedReader(inputReader);
        // 读取一行
        String line = null;
        StringBuffer strBuffer = new StringBuffer();
        while ((line = bufferReader.readLine()) != null)
        {
        	if(line.charAt(0)=='-'){  
                continue;  
            }else{
                strBuffer.append(line);
                strBuffer.append('\r');
            }
        }
        fis.close();
        inputReader.close();
        bufferReader.close();
        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(Base64.decode(strBuffer.toString()));
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        PublicKey publicKey = keyFactory.generatePublic(keySpec);
        return publicKey;
	}
	
	public static PrivateKey getPrivateKey(String privateFile) throws Exception{
		FileInputStream fis = new FileInputStream(privateFile);
		InputStreamReader inputReader = new InputStreamReader(fis);
		BufferedReader bufferReader = new BufferedReader(inputReader);
        // 读取一行
        String line = null;
        StringBuffer strBuffer = new StringBuffer();
        while ((line = bufferReader.readLine()) != null)
        {
            if(line.charAt(0)=='-'){  
                continue;  
            }else{
                strBuffer.append(line);
                strBuffer.append('\r');
            }
        }
        fis.close();
        inputReader.close();
        bufferReader.close();
        PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(Base64.decode(strBuffer.toString()));
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        PrivateKey privateKey = keyFactory.generatePrivate(keySpec);
        return privateKey;
	}
	
	public static void wiriteKeyToFile(String privateFile, String publicFile, String[] strings)
			throws IOException {
		FileOutputStream fosPrivate = new FileOutputStream(privateFile);
		FileOutputStream fosPublic = new FileOutputStream(publicFile);
		fosPrivate.write(strings[0].getBytes());
		fosPublic.write(strings[1].getBytes());
		fosPrivate.close();
		fosPublic.close();
	}

	public static void getPhoto(HttpServletResponse response, String path) throws Exception {
		File file = new File(path);
		FileInputStream fis;
		fis = new FileInputStream(file);

		long size = file.length();
		byte[] temp = new byte[(int) size];
		fis.read(temp, 0, (int) size);
		fis.close();
		byte[] data = temp;
		response.setContentType("image/png");
		OutputStream out = response.getOutputStream();
		out.write(data);
		out.flush();
		out.close();

	}
	public static void moveFile(String sourceDir,String sourceFile, String targetDir){
		int index = sourceFile.indexOf("/");
		String dir = sourceFile.substring(0, index);
		String targetFileDir = targetDir + File.separator + dir;
		File file = new File(targetFileDir);
		if(!file.exists()) {
			file.mkdirs();
		}
		file = new File(sourceDir + File.separator + sourceFile);
		if (file.renameTo(new File(targetFileDir + File.separator + file.getName()))) {
			System.out.println("File is moved successful!");
		} else {
			System.out.println("File is failed to move!");
		}
	}

	//@时间：2018/8/1 15:21
	//@描述：上传图片
	public static void uploadFile(MultipartFile file, String filePath) throws BusinessException {

		// 图像上传地址
		Assert.notNull(file, "上传图片不能为空！");
		Assert.hasText(filePath, "上传图片路径不能为空！");

		//图片文件夹
		String folderPath = filePath.substring(0, filePath.lastIndexOf(File.separator) + 1);

		// 如果该用户已上传过图片，删除对应图片
		File dirFile = new File(folderPath);
		if (!dirFile.exists()) {
			dirFile.mkdirs();
		}

		try {
			FileCopyUtils.copy(file.getBytes(), new File(filePath));
		} catch (IOException e) {
			log.debug("文件上传服务器失败：" + e.getMessage());
			throw new BusinessException(RespCode.FILE_UPLOAD_ERROR
					, RespCode.FILE_UPLOAD_ERROR_MSG);
		}
	}

	//@时间：2018/8/1 16:14
	//@描述：获取相对路径
	public static String getReleativePath(String extFolder, String orininalFilename) {

		String suffix = orininalFilename.substring(orininalFilename.lastIndexOf("."));

		//构造中间文件夹
		StringBuffer filePath = new StringBuffer();
		filePath.append(DateUtil.getCurrentDate4Pattern(DateUtil.DAY_FORMAT)).append(File.separator);
		if (StringUtil.isNotEmpty(extFolder)) {
			filePath.append(extFolder).append(File.separator);
		}
		filePath.append(SysHelper.getDateSerialNo())
				.append(suffix);
		return filePath.toString();
	}

	//@时间：2018/8/1 15:25
	//@描述：生成绝对文件路径
	public static String getFilePath(String rootPath, String fileName) {

		//构造中间文件夹
		StringBuffer filePath = new StringBuffer(rootPath)
				.append(fileName);
		return filePath.toString();
	}

	//@时间：2018/8/1 16:22
	//@描述：获取展示路径
	public static String getViewPath(String path, String fileName) {

		if (StringUtil.isEmpty(fileName)) {
			return "";
		} else if (fileName.contains("\\")) {
			fileName = fileName.replaceAll("\\\\", "/");
		}
		//构造中间文件夹
		StringBuffer viewPath = new StringBuffer(path);
		viewPath.append(fileName);
		return viewPath.toString();
	}

	//@时间：2018/8/1 17:28
	//@描述：获取真实路径
	public static String getRealPath(String oldPrefix, String newPrefix, String imagePath) {
		return imagePath.replace(oldPrefix, newPrefix).replaceAll("/", "\\\\");
	}

	public static void deleteFile(File file) {
		if (file.exists()) { // 判断文件是否存在
			if (file.isFile()) { // 判断是否是文件
				file.delete();
			} else if (file.isDirectory()) { // 否则如果它是一个目录
				File files[] = file.listFiles(); // 声明目录下所有的文件 files[];
				for (int i = 0; i < files.length; i++) { // 遍历目录下所有的文件
					deleteFile(files[i]); // 把每个文件 用这个方法进行迭代
				}
			}
			file.delete();
		} else {
			log.debug("所删除的文件不存在！" + '\n');
		}
	}
}
